{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def random_binning(N, d,return_string=False):\n",
    "    \"\"\"\n",
    "    Function to distribute a sum total of N into d bins\n",
    "    Returns a list\n",
    "    \"\"\"\n",
    "    import numpy as np\n",
    "    \n",
    "    count=N\n",
    "    sum_count=0\n",
    "    lst=[]\n",
    "    for i in range(d-1):\n",
    "        x=np.random.randint(0,count+1)\n",
    "        if return_string:\n",
    "            lst.append(str(x))\n",
    "        else:\n",
    "            lst.append(x)\n",
    "        count=count-x\n",
    "        sum_count+=x\n",
    "        \n",
    "    if return_string:\n",
    "        lst.append(str(N-sum_count))\n",
    "    else:\n",
    "        lst.append(N-sum_count)\n",
    "    return lst"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Function to generate single term from a list of exponents. E.g. if we pass 1,2,0,3 it will generate: $x_1.x_2^2.x_4^3$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def gen_single_term(lst):\n",
    "    \"\"\"\n",
    "    Function to generate single term from a list of exponents.\n",
    "    \"\"\"\n",
    "    term=''\n",
    "    for i in range(1,len(lst)+1):\n",
    "        if lst[i-1]==0:\n",
    "            pass\n",
    "        elif lst[i-1]==1:\n",
    "            term+='x'+str(i)+'.'\n",
    "        else:\n",
    "            term+='x'+str(i)+'^'+str(lst[i-1])+'.'\n",
    "    \n",
    "    return term[:-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'x1.x2.x3^2.x5'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gen_single_term([1,1,2,0,1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def count_symbol(lst):\n",
    "    syms = set(lst)\n",
    "    syms_dict={}\n",
    "    term_lst=[]\n",
    "    for s in syms:\n",
    "        syms_dict[s]=lst.count(s)\n",
    "    \n",
    "    for k,v in syms_dict.items():\n",
    "        if v!=1:\n",
    "            term_lst.append(str(v)+'.'+k)\n",
    "        else:\n",
    "            term_lst.append(k)\n",
    "    \n",
    "    return term_lst"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def gen_multinomial(n_features=5,max_power=5,max_terms=10,fixed_terms=None,coefficients=True,\n",
    "                   prob_negative_sign=0.3):\n",
    "    \"\"\"\n",
    "    Generates multinomial expression.\n",
    "    n_features: Number of independent variables\n",
    "    max_power: Maximum exponent each terms can be raised to. A random power will be chosen up to this maximum.\n",
    "    max_terms: Maximum number of terms. A random number of terms will be chosen up to this maximum.\n",
    "    fixed_terms: Attempt will be made to generate only this many terms. Sometimes does not work.\n",
    "    coefficients (boolean): Adds (or does not) random integer coefficients in front of the terms.\n",
    "    prob_negative_sign: Probability of putting a negative term. \n",
    "                        Each term's sign wil be chosen randomly based on this probability\n",
    "    \"\"\"\n",
    "    import numpy as np\n",
    "    eqn=''\n",
    "    eqn_terms=[]\n",
    "    \n",
    "    if fixed_terms!=None:\n",
    "        n_terms=fixed_terms\n",
    "    else:\n",
    "        n_terms=np.random.randint(2,max_terms+1)\n",
    "    \n",
    "    for i in range(n_terms):\n",
    "        power=np.random.randint(1,max_power+1)\n",
    "        #power=max_power\n",
    "        power_lst=random_binning(power,n_features)\n",
    "        term=gen_single_term(power_lst)\n",
    "        if coefficients:\n",
    "            coeff=np.random.randint(1,11)\n",
    "            if coeff!=1:\n",
    "                coeff=str(coeff)\n",
    "                term=coeff+'.'+term\n",
    "        eqn_terms.append(term)\n",
    "    \n",
    "    eqn_terms=count_symbol(eqn_terms)\n",
    "    \n",
    "    for e in eqn_terms:\n",
    "        eqn+=e\n",
    "        sign=np.random.choice(['+','-'],p=[prob_negative_sign,1-prob_negative_sign])\n",
    "        eqn= eqn+' '+sign+' '\n",
    "      \n",
    "    return eqn[:-3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'6.x1^2.x2.x4 - 4.x1^2.x4^3 - 7.x1^2.x2^2 - 3.x1 - 7.x1^3.x3.x5 - 5.x1^5 - 6.x5'"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gen_multinomial(coefficients=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def make_equation_system(n_samples=10,n_features=5,max_power=5,max_terms=10,\n",
    "                               fixed_terms=None,coefficients=False,prob_negative_sign=0.3):\n",
    "    \"\"\"\n",
    "    Generates multiple samples of multinomials for constructing a system of equations\n",
    "    \"\"\"\n",
    "    regressions=[]\n",
    "    for i in range(n_samples):\n",
    "        regressions.append(gen_multinomial(n_features=n_features,max_power=max_power,\n",
    "                                           max_terms=max_terms,fixed_terms=fixed_terms,\n",
    "                                           coefficients=coefficients,prob_negative_sign=prob_negative_sign))\n",
    "    \n",
    "    return regressions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['10.x2 - x1 - 7.x1 - 6.x1',\n",
       " '2.x2.x4^2 - 2.x1 + 8.x1.x2.x4 - 10.x4',\n",
       " '8.x1^2 - 4.x1.x2 + 6.x1^3 + 4.x1',\n",
       " '2.x1^3 + 3.x1.x2^2 - 9.x1^2.x4 - 9.x1',\n",
       " '7.x1.x3 - x1^3 + x1^2.x3 + 3.x2^2.x3',\n",
       " '10.x2^2.x4 - 8.x2 + 5.x1.x3 + x2^2.x4',\n",
       " '2.x1^3 - x1.x4 - 5.x1^2 + 2.x3',\n",
       " '10.x1 + 4.x1.x2 - 9.x1^2.x4 + 3.x1^2.x4',\n",
       " 'x2 - x1^3 + x2.x3^2 - 10.x1^2',\n",
       " '3.x1.x2.x4 - 3.x1^3 + 3.x1^2 - 3.x1']"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "make_equation_system(n_samples=10,n_features=4,max_power=3,max_terms=8,fixed_terms=4,\n",
    "                     coefficients=True,prob_negative_sign=0.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Evaluate a polynomial string"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sympy import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "def symbolize(s):\n",
    "    \"\"\"\n",
    "    Converts a a string (equation) to a SymPy symbol object\n",
    "    \"\"\"\n",
    "    from sympy import sympify\n",
    "    s1=s.replace('.','*')\n",
    "    s2=s1.replace('^','**')\n",
    "    s3=sympify(s2)\n",
    "    \n",
    "    return(s3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "def eval_multinomial(s,vals=None,symbolic_eval=False):\n",
    "    \"\"\"\n",
    "    Evaluates polynomial at vals.\n",
    "    vals can be simple list, dictionary, or tuple of values.\n",
    "    vals can also contain symbols instead of real values provided those symbols have been declared before using SymPy\n",
    "    \"\"\"\n",
    "    from sympy import Symbol,sympify,symbols\n",
    "    \n",
    "    sym_s=symbolize(s)\n",
    "    sym_set=sym_s.atoms(Symbol)\n",
    "    sym_lst=[]\n",
    "    for s in sym_set:\n",
    "        sym_lst.append(str(s))\n",
    "    sym_lst.sort()\n",
    "    if symbolic_eval==False and len(sym_set)!=len(vals):\n",
    "        print(\"Length of the input values did not match number of variables and symbolic evaluation is not selected\")\n",
    "        return None\n",
    "    else:\n",
    "        if type(vals)==list:\n",
    "            sub=list(zip(sym_lst,vals))\n",
    "        elif type(vals)==dict:\n",
    "            l=list(vals.keys())\n",
    "            l.sort()\n",
    "            lst=[]\n",
    "            for i in l:\n",
    "                lst.append(vals[i])\n",
    "            sub=list(zip(sym_lst,lst))\n",
    "        elif type(vals)==tuple:\n",
    "            sub=list(zip(sym_lst,list(vals)))\n",
    "        result=sym_s.subs(sub)\n",
    "    \n",
    "    return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "s1=gen_multinomial(fixed_terms=5,coefficients=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'2.x4 - 6.x2^2.x3 - 10.x1 - 6.x3^2.x4^2 - 8.x1^3.x2.x5'"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-266"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "eval_multinomial(s1,{'x1':2,'x3':1,'x4':0,'x2':3,'x5':1},symbolic_eval=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Length of the input values did not match number of variables and symbolic evaluation is not selected\n"
     ]
    }
   ],
   "source": [
    "vals=(2,3,1)\n",
    "eval_multinomial(s1,vals)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-12*x**2 - 64*x*y - 112"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy import symbols\n",
    "x,y=symbols('x y')\n",
    "vals=[2,x,2,2,y]\n",
    "eval_multinomial(s1,vals,symbolic_eval=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Pretty printing and LaTeX format output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "def pretty_multinomial(n_features=5,max_power=5,max_terms=10,fixed_terms=None,coefficients=False):\n",
    "    from sympy import init_printing\n",
    "    init_printing()\n",
    "    s=gen_multinomial(n_features=n_features,max_power=max_power,max_terms=max_terms,\n",
    "                      fixed_terms=fixed_terms,coefficients=coefficients)\n",
    "    sym_s=symbolize(s)\n",
    "    return(sym_s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAR4AAAAZBAMAAAAVlVzpAAAAMFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAIom7VJlmdt1E780QqzJwzRuQAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAD1klEQVRIDY2WT2hUVxTGv5mMM/PGl5lBUIgbQyDYRdBAFSkUlNJFEalDITaLCANC685BSANicSgFF104FcWumnQjiEJdqAhT5CGI0lKSuHGnaYs7JWkJDUI0nnvvufee9978u4vc757zu987nPvy7gBijB+M7EpIG4rPfQGJDwgnsGx1+Da7CCl9ve4LeBQYEE5ixWr5X7YRUhp73RfwKDAgnMSKrcwbW4+X0thrwfpgNzUgnMZym85SSBeLib6ApAeEk1ix4UyEdLGY6AtIekBYYTvGDrid405BSB/MfrPPLToCLpsQPeBHY8sOJixTw/E6B/I1lxGSY0cj4A6eVNOs29RVpN0cGl7H7ohXCiuso9Lk9WX8zApC6lD49EWE/AKyt9Os3YNcw8m4SLqJ7PAChqkMPRQW3ECFn1G+8+nHnBGSIzgTYWgJ9o3rAKBrPR1h9qWHZ9eMtpg9r9LWFmcgpKinsoRg3aw7AN3r6Qiz7+IkCvzVYyz8Dnj87cjZhiGEtKXomfqzWEOw0YO15xXOLV/bm3QTQelbov68kZ6ZD2YQjuYvFs2pCSm3QZ3XnlGUNwRgZPn5rrpBbT0PcbrxA/APpLEJvv7rq7gtHdb2/4UnZc+1slF2M6hqUMj4RlVPDeX/BGBksPWWSVvPBPZHP+LlNN1c3tgE57eW4rY4hE/WBUbZ0q0QQ5MkyvSHpblqw7YeK8rCnleKDT6PVD7bbt+/2W6rx0X4UEV+irmZ4JVXKoM/tO8DJXNf//3OeOpGZ6oYone00qByppoKUDJ51VKY6qH3OZdmgxW1Sw3bH2BDLamemJsKug+KyvEYpltKPVQ3urKp61ldoWTQVISSyauWwlQPNTFPexNs8OVsRHkarp7yO7XU9Xg3Hbw6N6NSsbGdeqow3ejSJIqbuegCCpGux8j0Vavq0d/DFJtp5SeNv63nWGEN53U9ws0ER3AqVgvyt7BaNZhudL5O98X8kcPYZfrD0n343O4LEfA9fl/pwNqfTVxPsD60lqnrerybDdLTnaUShd/CezCYafTVqY/w59zjE2SgzoslkjfyyV/v1vFw7rkFPLstCvlnE9cTPjs/q/6r6by8GwdnsNiilBhjUy3GfKM5bd4fs+hxI2vAs6Vqhl4qNex5mZV5f4x2br9gT8TpDpNtNKf8M9DjRjawZ+njUTOxMGIjM33mVt5tovMPGU36RvNG/4zU/e6srRDs2Bc2GJt3Xnpm1/5+z46P2mBq9o3mVK5pGXvV2nV6zjXTsW6R/m56p2+0McpMv22wZa8bWSOC5S09pr5uvJca/R6iRmagvpUtyAAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$3 x_{1}^{2} x_{2}^{2} - 10 x_{1}^{2} x_{5} + x_{1} x_{2}^{2} x_{5} - 9 x_{5}^{2}$$"
      ],
      "text/plain": [
       "    2   2        2           2          2\n",
       "3⋅x₁ ⋅x₂  - 10⋅x₁ ⋅x₅ + x₁⋅x₂ ⋅x₅ - 9⋅x₅ "
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pretty_multinomial(coefficients=True,fixed_terms=4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "def latex_multinomial(n_features=5,max_power=5,max_terms=10,fixed_terms=None,coefficients=False):\n",
    "    from sympy import latex\n",
    "    s=gen_multinomial(n_features=n_features,max_power=max_power,max_terms=max_terms,\n",
    "                      fixed_terms=fixed_terms,coefficients=coefficients)\n",
    "    sym_s=symbolize(s)\n",
    "    return(latex(sym_s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'5 x_{1}^{4} - 10 x_{1}^{2} x_{2} x_{5} + x_{1}^{2} x_{3} - 10 x_{2}^{3}'"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "latex_multinomial(coefficients=True,fixed_terms=4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/latex": [
       "$$\\left [ - 3 x_{1}^{4} x_{2} + 7 x_{1}^{3} + 9 x_{1}^{2} x_{2} x_{3} + 10 x_{1} x_{2}^{3} - x_{1} x_{5} + 7 x_{2}^{3} - 8 x_{3}^{5}, \\quad 2 x_{1}^{5} + 13 x_{1}^{2} - 7 x_{1} x_{2} + 10 x_{1} + 9 x_{4}, \\quad x_{1}^{5} + 4 x_{1}^{2} x_{2} - 6 x_{1}^{2} - 10 x_{1} x_{2}^{2} + 8 x_{1} x_{5} - 5 x_{1} - 4 x_{2}^{3} - x_{3}, \\quad - 8 x_{1}^{2} x_{2} + 6 x_{2}^{3} x_{3} x_{4} + 10 x_{2}^{3}, \\quad - 7 x_{1}^{4} + 7 x_{1}^{2} x_{3}^{2} x_{5} - 2 x_{1} x_{2} - 4 x_{1} + 10 x_{2}^{3} x_{3} - 9 x_{2}^{3} + 4 x_{2} + 7 x_{4}, \\quad 2 x_{1}^{5} - x_{1}^{2} x_{2} + x_{1} x_{2} x_{3} x_{5} - 2 x_{3}^{2}\\right ]$$"
      ],
      "text/plain": [
       "⎡      4          3       2                 3               3       5      5  \n",
       "⎣- 3⋅x₁ ⋅x₂ + 7⋅x₁  + 9⋅x₁ ⋅x₂⋅x₃ + 10⋅x₁⋅x₂  - x₁⋅x₅ + 7⋅x₂  - 8⋅x₃ , 2⋅x₁  +\n",
       "\n",
       "      2                             5       2          2           2          \n",
       " 13⋅x₁  - 7⋅x₁⋅x₂ + 10⋅x₁ + 9⋅x₄, x₁  + 4⋅x₁ ⋅x₂ - 6⋅x₁  - 10⋅x₁⋅x₂  + 8⋅x₁⋅x₅\n",
       "\n",
       "              3             2          3              3        4       2   2  \n",
       " - 5⋅x₁ - 4⋅x₂  - x₃, - 8⋅x₁ ⋅x₂ + 6⋅x₂ ⋅x₃⋅x₄ + 10⋅x₂ , - 7⋅x₁  + 7⋅x₁ ⋅x₃ ⋅x\n",
       "\n",
       "                          3          3                    5     2             \n",
       "₅ - 2⋅x₁⋅x₂ - 4⋅x₁ + 10⋅x₂ ⋅x₃ - 9⋅x₂  + 4⋅x₂ + 7⋅x₄, 2⋅x₁  - x₁ ⋅x₂ + x₁⋅x₂⋅x\n",
       "\n",
       "           2⎤\n",
       "₃⋅x₅ - 2⋅x₃ ⎦"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lst=[]\n",
    "for i in range(6):\n",
    "    lst.append(pretty_multinomial(coefficients=True))\n",
    "lst"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAALUAAAAZBAMAAACFo3IPAAAAMFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAEM0ymYmrIu9mu3ZEVN3VBPhYAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACd0lEQVRIDaVUMWhTURQ9n/gNTRN9FBShgxLBSTSILi6pYqGKlIhtHRxSRFDoYAcXQRC7F//goIvJKC6mtbpkaDaHgq2jghocFIxijVpB0Xj/f+/mv//eTyr+P+Sde889575/w79A38c9dawvn4Q8hwtJ5H2171Gc7VuQgPyIG40E8k2kb8QmBQnoVgItS53RqbjJuiNcIM/Uu9HJyWhKi9z6WS3qwl1e+mY3CMHtEAZooNPpbBi5bujsx/FuoIHLwEUtVDBbyhYi2S30ctORDAW5msxkRvDA5Py4DZTt/KFXL0Uk6wJutBvR7L1KjWMe5yewbFO3Oh2reMXKsPd9i5GJObp3w6lfWjkvYw0aiiow/OT641qYZu/2kaUGYoQ0kIPeDtyrvQWOkkzB0ICR68EpDbS27UGqqnLK22l7+KSEkUWUqeXKa2dQFk9xeJw0ErKhdu6miQv3S3Y2daKp0uxN8xsTUhgsoqG8/+wFXjwqF4T8n5+RRkLVvltExCLgIFMllG3SD9x8/sBcPj9N8A9QaUihuYiuCOCXX+57SxizBz/43HZ/2tKbAM+bxlnxpNBcRPuA1FdfGXgH0GxPZPDlFAuELG/6RioN5QFtEd0RqR94PriOBektodmeun+je4plDArbuygwxh5o+beUz6IY8rK/M+tpeim6N0O9fVCY+w6srj3EtZh7by058yzUF5E7cRrOzMLSXXIgb4Z6+8A7PQ/srA+fpCtYM8HEVIGF5iKSb6DmLQO9PdN82t7MUF9zETH1mgHQq71fkWuqOkcoEB7WIlLU1c8zXNSzPRWkxzdqXGedcYvIKOrV3ij7r/Af2vf2/Qu+R7fiBF5xGAAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$- 9 x_{1} x_{2}^{2} - 7 x_{1} + 6 x_{2}$$"
      ],
      "text/plain": [
       "         2              \n",
       "- 9⋅x₁⋅x₂  - 7⋅x₁ + 6⋅x₂"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pretty_multinomial(n_features=2,max_power=4,coefficients=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  },
  "latex_envs": {
   "LaTeX_envs_menu_present": true,
   "autoclose": false,
   "autocomplete": true,
   "bibliofile": "biblio.bib",
   "cite_by": "apalike",
   "current_citInitial": 1,
   "eqLabelWithNumbers": true,
   "eqNumInitial": 1,
   "hotkeys": {
    "equation": "Ctrl-E",
    "itemize": "Ctrl-I"
   },
   "labels_anchors": false,
   "latex_user_defs": false,
   "report_style_numbering": false,
   "user_envs_cfg": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
